<template>
  <teleport :to="teleportEl">
    <div class="tour-instance" v-if="visible">
      <!-- 遮罩层 -->
      <TheMask :pos="maskPos" :visible="maskVisible" @close="finishTour"></TheMask>
      <!-- step内容 -->
      <TheContent :pos="maskPos" :desc="currentStepConfig.description" :title="currentStepConfig.title"
        :current-step="currentStep + 1" :total-steps="steps.length" @prev="prevStep" @next="nextStep"
        @finish="finishTour" @skip="skipTour"></TheContent>
    </div>
  </teleport>
</template>

<script setup>
import { defineProps, ref, defineEmits, watch, onMounted, nextTick, onUnmounted } from 'vue';
import TheMask from './mask.vue';
import TheContent from './content.vue';

const props = defineProps({
  // 显示隐藏
  modelValue: {
    type: Boolean,
    default: false
  },
  // 所有的步骤
  steps: {
    type: Array,
    required: true,
    validator: (value) => {
      return value.every(step => step.target && (typeof step.target === 'string' || step.target instanceof HTMLElement));
    }
  },
  // 这个导游内容卡片渲染到那里
  teleport: {
    type: [String, HTMLElement],
    default: 'body'
  },
});

// 定义emits
const emit = defineEmits(['update:modelValue', 'finish', 'skip', 'change']);

// 响应式变量
const visible = ref(props.modelValue);
const maskVisible = ref(true);
const teleportEl = ref(typeof props.teleport === 'string' ? document.querySelector(props.teleport) : props.teleport);
const currentStep = ref(0);
const maskPos = ref({
  x: 0,
  y: 0,
  width: 0,
  height: 0,
});
const currentStepConfig = ref({});

// 监听modelValue变化
watch(() => props.modelValue, (newValue) => {
  visible.value = newValue;
  if (newValue) {
    nextTick(() => updateStep());
  }
}, { immediate: true });

// 监听窗口大小变化，重新计算位置
const handleResize = () => {
  if (visible.value) {
    updateStep();
  }
};

onMounted(() => {
  window.addEventListener('resize', handleResize);
  if (visible.value) {
    updateStep();
  }
});

// 清理事件监听
onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});

// 更新当前步骤
const updateStep = () => {
  if (!props.steps || !props.steps.length) return;

  currentStepConfig.value = props.steps[currentStep.value] || {};
  emit('change', currentStep.value, currentStepConfig.value);

  // 获取目标元素
  const targetEl = typeof currentStepConfig.value.target === 'string'
    ? document.querySelector(currentStepConfig.value.target)
    : currentStepConfig.value.target;

  if (!targetEl) {
    return;
  }

  // 获取目标元素位置信息
  const rect = targetEl.getBoundingClientRect();
  const bodyRect = document.body.getBoundingClientRect();

  // 计算相对于body的位置
  maskPos.value = {
    x: rect.left - bodyRect.left - 4,
    y: rect.top - bodyRect.top - 4,
    width: rect.width + 8,
    height: rect.height + 8,
  };
};

// 下一步
const nextStep = () => {
  if (currentStep.value < props.steps.length - 1) {
    currentStep.value++;
    updateStep();
  } else {
    finishTour();
  }
};

// 上一步
const prevStep = () => {
  if (currentStep.value > 0) {
    currentStep.value--;
    updateStep();
  }
};

// 结束引导
const finishTour = () => {
  visible.value = false;
  emit('update:modelValue', false);
  emit('finish');
  currentStep.value = 1;
};

// 跳过引导
const skipTour = () => {
  visible.value = false;
  emit('update:modelValue', false);
  emit('skip');
};
</script>

<style lang="scss" scoped>
.tour-instance {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
</style>